/*************
author:: libo
license:: MIT
*****************/
#ifndef LIB_CELL_FUNC_H
#define LIB_CELL_FUNC_H
#include "Mesh.h"
//#include <tools/intrbtree_iterator.h>
#include "libcell_iteratorc.h"
//#include "lib_cell_iterator.h"


#define iterator_v lib_cell_iterator_vertices
#define iterator_f lib_cell_iterator_faces
#define iterator_c lib_cell_iterator_cells
#define iterator_edge lib_cell_iterator_edge

//#include<iterator/cstruct_iterator.h>
#ifdef __cplusplus
extern "C"{
#endif

template_v* Mesh_get_vertexp(struct Mesh *m,int i);
template_c*  Mesh_get_cellp(struct Mesh*m,int i);
template_f* Mesh_get_facep(struct Mesh*m,int i);
template_hf* Mesh_get_halffacep(struct Mesh*m,int i);

template_v  Mesh_get_vertex(struct Mesh*,int);
template_c  Mesh_get_cell(struct Mesh*,int);
template_f Mesh_get_face(struct Mesh*,int);
template_hf Mesh_get_halfface(struct Mesh*,int);
template_f* Mesh_get_facev(struct Mesh*,template_v**,int);
template_c* Mesh_get_cellv(struct Mesh*,template_v**,int);
template_c* Mesh_get_cellf(struct Mesh*,template_f**,int);
// below functions will be deprecated


static inline void Mesh_insert_vertices(struct Mesh* m,int i,template_v*v)
{
    m->vertices->insert(m->vertices,i,v);
}
static inline void Mesh_insert_faces(struct Mesh* m,int i,template_f* f)
{
    m->faces->insert(m->faces,i,f); 
}
static inline void Mesh_insert_halffaces(struct Mesh* m,int i,template_hf*hf)
{
    m->halffaces->insert(m->halffaces,i,hf); 
}
static inline void Mesh_insert_cells(struct Mesh* m,int i,template_c*c)
{
    m->cells->insert(m->cells,i,c);
}
//above functions will be deprecated


int Mesh_num_v(struct Mesh*);
int Mesh_num_c(struct Mesh*);
int Mesh_num_f(struct Mesh*);
int Mesh_num_hf(struct Mesh*);

template_v * Mesh_create_vertex(struct Mesh*);
template_v* Mesh_create_vertexv(struct Mesh*,double*,int);
template_c * Mesh_create_cell(struct Mesh*);
template_f * Mesh_create_face(struct Mesh*) ;
//
//when exist,return existed cell
//when not exist,create new cell
//
template_c* Mesh_create_cellv(struct Mesh*,template_v**,int);
//when exist,return existed cell
//when not exist,create new cell
template_c* Mesh_create_cellf(struct Mesh*,template_hf**,int size);

//when exist,return existed face
//when not exist,create new face
template_f * Mesh_create_facev(struct Mesh*,template_v**,int);
template_hf* Mesh_create_halfface(struct Mesh*,template_f*,template_v**,int);
int Mesh_delete_vertex(struct Mesh*,template_v,int burning);
int Mesh_delete_face(struct Mesh*,template_f,int burning);
int Mesh_delete_halfface(struct Mesh*,template_hf,int burning);
int Mesh_delete_cell(struct Mesh*,template_c,int burning);

//孤立点也是边界点
int Mesh_vertex_is_boundary(struct Mesh*,template_v);
int  Mesh_nface_is_boundary(struct Mesh* own,template_f f);
int Mesh_face_is_boundary(struct Mesh*,template_f*);

int Mesh_cell_is_boundary(struct Mesh*,template_c );

int Mesh_face_is_in_cell(struct Mesh* own, template_f*f , template_c* c);
int Mesh_vertex_is_in_cell(struct Mesh* own,template_v*v, template_c*c);
int Mesh_vertex_is_in_face(struct Mesh* own, template_v*v, template_f*f);




Node* Mesh_node_of_boundary_face(struct Mesh*,template_f*);
void Mesh_external_cell_init_(struct Mesh*);
template_hf Mesh_opposite_halfface(template_hf);
template_hf* Mesh_s_opposite_halfface(template_hf*);
//void Mesh_cell_division(struct Mesh*,template_c*);
void Mesh_reset_c_prop(struct Mesh*);
void Mesh_reset_v_prop(struct Mesh*);
void Mesh_reset_hf_prop(struct Mesh*);
void Mesh_reset_f_prop(struct Mesh*);





iterator_v Mesh_v_beginn(struct Mesh * own);
iterator_v Mesh_v_endn(struct Mesh*own);

iterator_hf Mesh_hf_beginn(struct  Mesh*own);
iterator_hf Mesh_hf_endn(struct  Mesh*own);

iterator_f Mesh_f_beginn(struct  Mesh*own);
iterator_f Mesh_f_endn(struct  Mesh*own);

iterator_c Mesh_c_beginn(struct Mesh*own);
iterator_c Mesh_c_endn(struct Mesh*own);

//
iterator_v Mesh_fv_begin(struct Mesh*,template_f );
iterator_v Mesh_fv_end(struct Mesh*,template_f);
iterator_v Mesh_hfv_begin(struct Mesh*,template_hf);
iterator_v Mesh_hfv_end(struct Mesh*,template_hf);
iterator_v Mesh_cv_begin(struct Mesh*,template_c);
iterator_v Mesh_cv_end(struct Mesh*,template_c);

//iterator_f
iterator_f Mesh_vf_begin(struct Mesh*,template_v);
iterator_f Mesh_vf_end(struct Mesh*,template_v);
iterator_hf Mesh_chf_begin(struct Mesh*,template_c);
iterator_hf Mesh_chf_end(struct Mesh*,template_c);
//iterator_c

iterator_c Mesh_vc_begin(struct Mesh*,template_v);
iterator_c Mesh_vc_end(struct Mesh*,template_v);


Node* Mesh_vv_begin(struct Mesh*,template_v);
Node* Mesh_vv_end(struct Mesh*,template_v);
iterator_edge Mesh_edge_begin(struct Mesh*,template_v v,template_f  );
//iterator_edge Mesh_edge_end(struct Mesh*);

void Mesh_printself(struct Mesh*);
Node* Mesh_intersection_two_faces(struct Mesh*,template_f*,template_f*);
int Mesh_two_cell_is_connected(struct Mesh* own,template_c* c1,template_c* c2);
Node* Mesh_non_manifold_vertices(struct Mesh*);
int  Mesh_is_manifold_vertices(struct Mesh*own,template_v*v);



Mesh* mesh_duplicate(struct Mesh*  );

void Mesh_free(struct Mesh*);
void Mesh_init(struct Mesh*);


#ifdef __cplusplus
}
#endif
//bool mesh_delete_vertex(struct Mesh*,template_v *);
//bool mesh_delete_cell(struct Mesh*,template_c *);
//void mesh_rearrange_id(struct Mesh*);

#undef iterator_v 
#undef iterator_f 
#undef iterator_c 
#undef iterator_edge 
#endif
